home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "mancala.h"
- #include "rnd.h"
-
-
- static int owner[14] = {0,0,0,0,0,0,2,1,1,1,1,1,1,2};
- static int opposite[14] = {12,11,10, 9, 8, 7,0, 5, 4, 3, 2, 1, 0,0};
-
- static void player_move(ab_position_t *pos, ab_move_t *move);
- static void print_board(ab_position_t *pos);
-
-
- static rnd_t rndset;
-
-
- main(int argc, char *argv[]) {
- ab_position_t board;
- int i, sdepth[2];
- ab_move_t move;
- ab_storage_t useless_storage;
-
- rnd_init(&rndset, getpid() + time(0L));
- rnd_use(&rndset);
- if (argc != 3) {
- fprintf(stderr, "Usage: mancala <Search depth 1> <search depth 2>\n");
- exit(1);
- }
- sdepth[0] = atoi(argv[1]);
- sdepth[1] = atoi(argv[2]);
- for (i = 0; i < 14; ++i)
- board.pits[i] = 4;
- board.pits[6] = board.pits[13] = 0;
- board.player_to_move = 0;
- print_board(&board);
- do {
- if (sdepth[board.player_to_move] > 0) {
- move = ab_search(&board, sdepth[board.player_to_move]);
- printf("Comp move: %d\n",
- (move.pit+1)%7, move.score);
- } else
- player_move(&board, &move);
- ab_do_move(&board, &move, &useless_storage);
- print_board(&board);
- } while (board.pits[6] + board.pits[13] < 48);
- }
-
-
- static void player_move(ab_position_t *pos, ab_move_t *move) {
- if (ab_generate_moves(pos, NULL) == 0)
- move->pit = -1;
- else {
- do {
- printf("Move--> ");
- scanf("%d", &move->pit);
- move->pit = move->pit - 1 + 7*pos->player_to_move;
- } while ((owner[move->pit] != pos->player_to_move) ||
- (pos->pits[move->pit] == 0));
- }
- }
-
-
- int ab_generate_moves(ab_position_t *pos, ab_move_t *moves) {
- int nmoves = 0, i, pitnum;
- ab_storage_t storage;
-
- pitnum = pos->player_to_move * 7;
- for (i = 0; i < 6; ++i) {
- if (pos->pits[pitnum + i] != 0) {
- if (moves != NULL) {
- moves[nmoves].pit = pitnum + i;
- moves[nmoves].score = ab_do_move(pos, &moves[nmoves], &storage) +
- (rnd() & 1023);
- ab_undo_move(pos, &storage);
- }
- ++nmoves;
- }
- }
- if ((nmoves == 0) && (moves != NULL)) {
- moves[nmoves].pit = -1;
- moves[nmoves].score = 0;
- ++nmoves;
- }
- return(nmoves);
- }
-
-
- ab_score_t ab_do_move(ab_position_t *pos, ab_move_t *move,
- ab_storage_t *storage) {
- int i, pitnum, stones, skip_pit, score_pit, orig_pit, dead_pit;
- int score = 0;
-
- for (i = 0; i < 14; ++i) {
- storage->oldpits[i] = pos->pits[i];
- }
- storage->old_tomove = pos->player_to_move;
- pitnum = orig_pit = move->pit;
- if (pitnum == -1) {
- /* The null move. Only possible when there is no legal move. */
- pos->player_to_move ^= 1;
- return(0);
- }
- stones = pos->pits[pitnum];
- pos->pits[pitnum] = 0;
- if (pitnum < 7) {
- skip_pit = 13;
- score_pit = 6;
- } else {
- skip_pit = 6;
- score_pit = 13;
- }
- while (stones > 0) {
- ++pitnum;
- if (pitnum == skip_pit)
- ++pitnum;
- if (pitnum == 14)
- pitnum = 0;
- ++pos->pits[pitnum];
- if (pitnum == score_pit)
- ++score;
- --stones;
- }
- if ((pos->pits[pitnum] == 1) &&
- (owner[pitnum] == owner[orig_pit])) {
- dead_pit = opposite[pitnum];
- if (dead_pit > 13)
- dead_pit -= 14;
- score += pos->pits[dead_pit];
- pos->pits[score_pit] += pos->pits[dead_pit];
- pos->pits[dead_pit] = 0;
- }
- if (pitnum != score_pit)
- pos->player_to_move ^= 1;
- return(score * 1024);
- }
-
-
- void ab_undo_move(ab_position_t *pos, ab_storage_t *storage) {
- int i;
-
- for (i = 0; i < 14; ++i) {
- pos->pits[i] = storage->oldpits[i];
- pos->player_to_move = storage->old_tomove;
- }
- }
-
-
- int ab_move_cmp(ab_move_t *mv1, ab_move_t *mv2) {
- if (mv1->score == mv2->score)
- return(mv2->pit - mv1->pit);
- else
- return(mv2->score - mv1->score);
- }
-
-
- static void print_board(ab_position_t *pos) {
- printf(" 6 5 4 3 2 1\n");
- printf(" -- -- -- -- -- --\n");
- printf(" %2d|%2d|%2d|%2d|%2d|%2d\n",
- pos->pits[5], pos->pits[4], pos->pits[3],
- pos->pits[2], pos->pits[1], pos->pits[0]);
- printf(" %2d--+--+--+--+--+--%2d\n",
- pos->pits[6], pos->pits[13]);
- printf(" %2d|%2d|%2d|%2d|%2d|%2d\n",
- pos->pits[7], pos->pits[8], pos->pits[9],
- pos->pits[10], pos->pits[11], pos->pits[12]);
- printf(" -- -- -- -- -- --\n");
- printf(" 1 2 3 4 5 6\n\n");
- }
-